/******************************************************************************/
/* File: ctrlSocket.h                                                         */
/******************************************************************************/

/******************************************************************************/
/* Check to see if already included.                                          */
/******************************************************************************/
#ifndef CTRLSOCKET_H
#define CTRLSOCKET_H

#include <map>
#include <list>
#include <vector>
#include <fstream>
#include <iostream>
#include <string>
#include <time.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include "message.h"
#include "dataStore.h"
#include "thread.h"
#include "socketClass.h"
#include "messageQueue.h"
#include "tcpTrafficSender.h"
#include "tcpTrafficRecver.h"
#include "tcpTrafficServer.h"
#include "udpTrafficSender.h"
#include "udpTrafficRecver.h"
#include "udpTrafficServer.h"

class CtrlSender;

/******************************************************************************/
/*    CtrlClient Class                                                        */
/******************************************************************************/

class CtrlClient : public TCPClientSocket {
    
public:
    CtrlClient(IPAddress &cServAddr, int iServPort, bool bUseIPv6);
    virtual ~CtrlClient();
    
    // Add a new flow which is configured by pfc and pMsgQueue.
    bool AddNewFlow(FlowConfig *pfc, MessageQueue *pMsgQueue);
    
    // Modify existed flow.
    bool ModExistFlow(FlowConfig *pfc);
    
    // Delete existed flow.
    bool DelExistFlow(FlowConfig *pfc);
    
    // Handle recved message from remote control server.
    bool HandleRcvdJson(cJSON *json, MessageQueue *pMsgQueue);
    
    // Socket function wrapper. 
    void ConnectToServer();
    
    // Core function.
    void RunClient();

protected:
    IPAddress cServAddr;
    int iServPort;
};

/******************************************************************************/
/*    CtrlServer Class                                                        */
/******************************************************************************/

class CtrlServer : public TCPServerSocket {

public:
    
    // Default: IPAddress &cLocalAddr, int iLocalPort = 0, int iBackLog = 1, bool bUseIPv6 = false
    CtrlServer(CtrlServerSetting *pSet);
    
    virtual ~CtrlServer();
    
    void SendMessage(Message *pm, TCPSocket *pts);

    // Parse new traffic configuration
    bool HandleNewTrafficConfig();
    
    // Check the file modification time
    bool CheckFileModification();
    
    char* ReadFileToString(std::ifstream &file);
    
    // Utilization Functions
    int SetNonblocking(int fd, int nonblocking);
    
    // Accept connection and recv data
    void RunServer();

protected:    
    // ConfigFile fd
    std::ifstream file;
    
    // Filename
    char *fileName;
    
    // file status: 0 fileError; 1 fileExisted;  
    int fileStatus;
    
    // Record last modified time
    time_t lastModifiedTime;
};

/******************************************************************************/
/*    CtrlServer Class                                                        */
/******************************************************************************/

class CtrlSender : public Thread {

public:
    CtrlSender(CtrlClient *pcc, MessageQueue *pmq);
    ~CtrlSender();
    
    // Core function.
    virtual void Run();
    
protected:
    CtrlClient *pCtrlClient;
    MessageQueue *pMsgQueue;
};

#endif

/******************************************************************************/
/* End File: ctrlSocket.h                                                     */
/******************************************************************************/
